-- task.lua
-- 任务对象
-- 异步执行的任务

Task = class(Object);

-- 公共的方法
function Task.post(id, msg, flag)
    flag = flag or 0;
    if is_table(msg) then
        local msg = table.save(msg);
        return task.post(id, msg, flag);
    else
        return task.post(id, tostring(msg), flag);
    end
end

-- 构造函数
function Task:__init(task_key, taskid)
    self[Object]:__init(); 
    self.taskid = taskid;
    self.taskkey = task_key;
    self.parentid = task.id();

    -- 默认0.1秒检查一次接收消息
    self.recv_interval = 0.1;
end

-- 析构函数
function Task:__destroy()
    task.cancel(self.taskid);
end

-- 设置任务监听器
-- 从task那边收到消息会通知监听器
function Task:set_listener(listener)
    self.listener = listener;
end

-- 设置接收消息的频率
function Task:set_receive_freq(freq)
    self.recv_interval = 1 / freq;
end

-- 外部向任务发送消息
function Task:send_message(msg_id, ...)

    -- 组织传送的数据
    local send_content = {
        msg_id,
        task.id(),
        {...},
    }

    -- post数据
    local res = task.post(self.taskid, table.save(send_content));
    if res == -1 then
        return false, 'task is not running';
    elseif res == -2 then
        return false, 'can not malloc message entry';
    else
        return true;
    end
end

-- 任务向外部传递消息
function Task:post_message(msg_id, table_msg)
    assert(is_table(table_msg));

    -- 组织传送的数据
    local send_content = {
        msg_id,
        task.id(),
        table.save(table_msg),
    }

    local res = task.post(self.parentid, table.save(send_content));
    if res == -1 then
        return false, 'task is not running';
    elseif res == -2 then
        return false, 'can not malloc message entry';
    else
        return true;
    end
end

-- 通知收到消息
function Task:_notify_msg_receive(id, ...)
    if id == 'exit' then
        -- 退出
        TASK_MGR.delete_task(self.taskkey);
        return;
    end

    if self.listener then
        local funname = 'on_task_msg_'..string.lower(id);
        local fun = self.listener[funname];
        if fun == nil then
            fun = self.listener['on_task_msg_receive'];
        end

        if fun ~= nil then
            fun(self.listener, ...);
        else
            logger:warn(string.format('receive msg <%s> but not handle it.', id));
        end
    else
        logger:warn(string.format('task has no listener, msg <%s> is ignored', id));
    end
end

